package com.csdj.payment.mq;

import com.csdj.beans.entity.Order;
import com.csdj.beans.entity.PayHis;
import com.csdj.common.constant.PaymentConstant;
import com.csdj.common.constant.WebResultConstant;
import com.csdj.payment.service.PayService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;

@Component
public class PaymentMsgListener implements TransactionListener {


    @Resource
    private PayService payService;
    private ObjectMapper om = new ObjectMapper();

    private Logger log = LoggerFactory.getLogger("paymentListener");


    @PostConstruct
    public void init(){
        log.info("transaction listener start ");
    }
    /**
     * 监听事务消息， 确认消息是否要真正发送到队列中还是回滚
     * @param msg
     * @param arg
     * @return
     */
    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        //监听到发送事务消息后，执行实际支付扣款动作  如果成功则确认消息， 如果 失败则回滚消息
        if(PaymentConstant.PAYMENT_TAG.equals(msg.getTags())){
            try {
                Order order = om.readValue(msg.getBody(),Order.class);
                //支付动作
                if(WebResultConstant.SUCCESS == payService.updateBalance(order,(byte)arg)){
                    log.info("msgId:{} orderid:{} 确认发送",msg.getTransactionId(),order.getId());
                    return LocalTransactionState.COMMIT_MESSAGE;
                }else{
                    log.info("msgId:{} orderid:{} 消息回滚",msg.getTransactionId(),order.getId());
                    return LocalTransactionState.ROLLBACK_MESSAGE;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            log.info("消息处理发生异常，回滚消息");
            return LocalTransactionState.ROLLBACK_MESSAGE;
        }
        log.info("不是支付消息， 回滚消息");
        return null;
    }

    /**
     * 消息回查， 如果消息长时间没有被确认，则由些方法来复查
     * @param msg
     * @return
     */
    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt msg) {
        if(PaymentConstant.PAYMENT_TAG.equals(msg.getTags())){
            try {
                Order order = om.readValue(msg.getBody(),Order.class);
                //检查有没有支付记录，
                final PayHis his = payService.getHisByOrdreId(order.getId());
                if(his == null){
                    log.info("orderid:{}  没有支付，消息回滚");
                    return LocalTransactionState.ROLLBACK_MESSAGE;
                }else{
                    log.info("order:{} 已经支付，消息确认发送");
                    return LocalTransactionState.COMMIT_MESSAGE;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return LocalTransactionState.ROLLBACK_MESSAGE;
    }
}
